/*
 * SPDX-License-Identifier: Apache-2.0
 */

//===-------------------------- CompilerUtils.hpp -------------------------===//
//
// Copyright 2019-2022 The IBM Research Authors.
//
// =============================================================================
//
// Functions for adding passes and processing input files.
//
//===----------------------------------------------------------------------===//

#pragma once

#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/Support/FileUtilities.h"

#include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h"
#include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h"
#include "mlir/Conversion/VectorToSCF/VectorToSCF.h"
#include "mlir/InitAllDialects.h"
#include "mlir/Parser/Parser.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Transforms/Passes.h"
#include "llvm/ADT/SmallVector.h"

#include "onnx-mlir/Compiler/OMCompilerTypes.h"

#include "src/Builder/FrontendDialectTransformer.hpp"
#include "src/Compiler/CompilerOptions.hpp"
#include "src/Compiler/CompilerPasses.hpp"
#include "src/Dialect/Krnl/KrnlOps.hpp"
#include "src/Pass/Passes.hpp"

namespace onnx_mlir {
void registerDialects(mlir::MLIRContext &context);

// ProcessInput* return 0 on success, OnnxMlirCompilerErrorCodes on error.
int processInputFile(std::string inputFilename, mlir::MLIRContext &context,
    mlir::OwningOpRef<mlir::ModuleOp> &module, std::string *errorMessage);
int processInputArray(const void *onnxBuffer, int bufferSize,
    mlir::MLIRContext &context, mlir::OwningOpRef<mlir::ModuleOp> &module,
    std::string *errorMessage);

onnx_mlir::InputIRLevelType determineInputIRLevel(
    mlir::OwningOpRef<mlir::ModuleOp> &module);

// Returns 0 on success, OnnxMlirCompilerErrorCodes on failure.
int outputCode(mlir::OwningOpRef<mlir::ModuleOp> &module,
    std::string filenameWithExt, int64_t largeElementLimit = -1);

// Process the input model given by its module and context into an output file
// according to the emission target type. Name of the output file can be
// constructed using the getTargetFilename function below.  When  generating
// libraries or jar files, the compiler will link in lightweight runtimes / jar
// files. If these libraries / jar files are not in the system wide directory
// (typically /usr/local/lib), the user can override the default location using
// the ONNX_MLIR_RUNTIME_DIR environment variable.
// Returns 0 on success,OnnxMlirCompilerErrorCodes on failure.
int compileModule(mlir::OwningOpRef<mlir::ModuleOp> &module,
    mlir::MLIRContext &context, std::string outputNameNoExt,
    onnx_mlir::EmissionTargetType emissionTarget);

// Extend the input filename (with possibly a path but no extention) by the
// extention generated by the given emission target type. Names may be different
// depending on the underlying machine and/or operating system.
std::string getTargetFilename(
    const std::string filenameNoExt, EmissionTargetType target);
} // namespace onnx_mlir
